/**
数据访问对象模式（Data Access Object Pattern）

数据访问对象接口（Data Access Object Interface） - 该接口定义了在一个模型对象上要执行的标准操作。
数据访问对象实体类（Data Access Object concrete class） - 该类实现了上述的接口。该类负责从数据源获取数据，数据源可以是数据库，也可以是 xml，或者是其他的存储机制。
模型对象/数值对象（Model Object/Value Object） - 简单数值对象，包含了 get/set 方法来存储通过使用 DAO 类检索到的数据。
*/
main(List<String> args) {
  StudentDao studentDao = new StudentDaoImpl();

  //输出所有的学生
  for (Student student in studentDao.getAllStudents()) {
    print("Student: [RollNo : ${student.rollNo}, Name : ${student.name} ]");
  }

  //更新学生
  Student student = studentDao.getAllStudents()[0];
  student.name = "Michael";
  studentDao.updateStudent(student);

  //获取学生
  studentDao.getStudent(0);
  print("Student: [RollNo : ${student.rollNo}, Name : ${student.name} ]");
}

//////////////////////////////////////////////////////////////////

///
/// 创建数值对象
///
class Student {
  int rollNo;
  String name;

  Student(this.name, this.rollNo);
}

///
/// 创建数据访问对象接口
///
abstract class StudentDao {
  List<Student> getAllStudents();
  Student getStudent(int rollNo);
  void updateStudent(Student student);
  void deleteStudent(Student student);
}

///
/// 创建实现了上述接口的实体类
///
class StudentDaoImpl implements StudentDao {
  //列表是当作一个数据库
  List<Student> _students;

  StudentDaoImpl() {
    _students = List<Student>();
    Student student1 = Student("Robert", 0);
    Student student2 = Student("John", 1);
    _students.add(student1);
    _students.add(student2);
  }

  @override
  void deleteStudent(Student student) {
    _students.remove(student.rollNo);
    print("Student: Roll No ${student.rollNo}, deleted from database");
  }

  //从数据库中检索学生名单
  @override
  List<Student> getAllStudents() {
    return _students;
  }

  @override
  Student getStudent(int rollNo) {
    return _students[rollNo];
  }

  @override
  void updateStudent(Student student) {
    _students[student.rollNo]?.name = student.name;
    print("Student: Roll No ${student.rollNo}, updated in the database");
  }
}
